%{
#include "globals.h"
%}
%option noyywrap

D			[0-9]
L			[a-zA-Z_]
H			[a-fA-F0-9]
E			[Ee][+-]?{D}+
FS			(f|F|l|L)
IS			(u|U|l|L)*

%%
"/*"			{ comment(); }
"//"[^\n]*		{ /* consume //-comment */ }


"bool"			{ count(); return(BOOL); }
"break"			{ count(); return(BREAK); }
"case"			{ count(); return(CASE); }
"class"			{ count(); return(CLASS); } 
"char"			{ count(); return(CHAR); }
"const"			{ count(); return(CONST); }
"continue"		{ count(); return(CONTINUE); }
"default"		{ count(); return(DEFAULT); }
"do"			{ count(); return(DO); }
"double"		{ count(); return(DOUBLE); }
"dynamic"		{ count(); return(DYNAMIC); }
"else"			{ count(); return(ELSE); }
"extends"		{ count(); return(EXTENDS); }
"false"			{ count(); return(FALSE); }
"float"			{ count(); return(FLOAT); }
"for"			{ count(); return(FOR); }
"goto"			{ count(); return(GOTO); }
"if"			{ count(); return(IF); }
"import"		{ count(); return(IMPORT); }
"int"			{ count(); return(INT); }
"long"			{ count(); return(LONG); }
"null"			{ count(); return(NUL); }
"package"		{ count(); return(PACKAGE); }
"return"		{ count(); return(RETURN); }
"short"			{ count(); return(SHORT); }
"signed"		{ count(); return(SIGNED); }
"static"		{ count(); return(STATIC); }
"switch"		{ count(); return(SWITCH); }
"true"			{ count(); return(TRUE); }
"unsigned"		{ count(); return(UNSIGNED); }
"void"			{ count(); return(VOID); }
"while"			{ count(); return(WHILE); }

{L}({L}|{D})*	{ count(); yylval.ident=strdup(yytext);
				  return(check_type());
				}

0[xX]{H}+{IS}?	{ count(); yylval.ident=strdup(yytext);return(CONSTANT); }
0{D}+{IS}?		{ count(); yylval.ident=strdup(yytext);return(CONSTANT); }
{D}+{IS}?		{ count(); yylval.ident=strdup(yytext);return(CONSTANT); }
L?'(\\.|[^\\'])+'	{ count(); yylval.ident=strdup(yytext);return(CONSTANT); }

{D}+{E}{FS}?	{ count(); yylval.ident=strdup(yytext);return(CONSTANT); }
{D}*"."{D}+({E})?{FS}?	{ count(); yylval.ident=strdup(yytext);return(CONSTANT); }
{D}+"."{D}*({E})?{FS}?	{ count(); yylval.ident=strdup(yytext);return(CONSTANT); }

L?\"(\\.|[^\\"])*\"	{ count(); yylval.ident=strdup(yytext);return(STRING_LITERAL); }

"..."			{ count(); return(ELLIPSIS); }
">>="			{ count(); return(RIGHT_ASSIGN); }
"<<="			{ count(); return(LEFT_ASSIGN); }
"+="			{ count(); return(ADD_ASSIGN); }
"-="			{ count(); return(SUB_ASSIGN); }
"*="			{ count(); return(MUL_ASSIGN); }
"/="			{ count(); return(DIV_ASSIGN); }
"%="			{ count(); return(MOD_ASSIGN); }
"&="			{ count(); return(AND_ASSIGN); }
"^="			{ count(); return(XOR_ASSIGN); }
"|="			{ count(); return(OR_ASSIGN); }
">>"			{ count(); return(RIGHT_OP); }
"<<"			{ count(); return(LEFT_OP); }
"++"			{ count(); return(INC_OP); }
"--"			{ count(); return(DEC_OP); }
"->"			{ count(); return(PTR_OP); }
"&&"			{ count(); return(AND_OP); }
"||"			{ count(); return(OR_OP); }
"<="			{ count(); return(LE_OP); }
">="			{ count(); return(GE_OP); }
"=="			{ count(); return(EQ_OP); }
"!="			{ count(); return(NE_OP); }
";"				{ count(); return(';'); }
("{"|"<%")		{ count(); return('{'); }
("}"|"%>")		{ count(); return('}'); }
","				{ count(); return(','); }
":"				{ count(); return(':'); }
"="				{ count(); return('='); }
"("				{ count(); return('('); }
")"				{ count(); return(')'); }
("["|"<:")		{ count(); return('['); }
("]"|":>")		{ count(); return(']'); }
"."			{ count(); return('.'); }
"&"			{ count(); return('&'); }
"!"			{ count(); return('!'); }
"~"			{ count(); return('~'); }
"-"			{ count(); return('-'); }
"+"			{ count(); return('+'); }
"*"			{ count(); return('*'); }
"/"			{ count(); return('/'); }
"%"			{ count(); return('%'); }
"<"			{ count(); return('<'); }
">"			{ count(); return('>'); }
"^"			{ count(); return('^'); }
"|"			{ count(); return('|'); }
"?"			{ count(); return('?'); }

[ \t\v\n\f]		{ count(); }
.			{ error("Bad character."); }

%%

void comment(void)
{
	char c, prev = 0;
  
	while ((c = input()) != 0)      /* (EOF maps to 0) */
	{
		if(c=='\n') __line++;
		if (c == '/' && prev == '*')
			return;
		prev = c;
	}
	error("unterminated comment");
}

void count(void){
	int i;

	for (i = 0; yytext[i] != '\0'; i++)
		if (yytext[i] == '\n'){
			__column = 0;
			__line++;
		}
		else if (yytext[i] == '\t')
			__column += 4 - (__column % 8);
		else
			__column++;

	//ECHO;
}


int check_type(void){
	Import *imp;
	for(imp=program->imports;imp;imp=imp->next){
//		printf("TYPE: '%s' PACKAGE: '%s' FULLNAME: '%s'\n", imp->class, imp->package, imp->fullname);
		if(strcmp(yytext, imp->fullname)==0) return OBJECT;
		if(strcmp(yytext, imp->class)==0) return OBJECT;
	}

	return(IDENT);
}
